﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;

namespace Workflows.Components.TextMining.Collapse
{
    /// <summary>
    /// 
    /// </summary>
    public class ReverseIndexCluster
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="dt"></param>
        /// <param name="fieldName"></param>
        /// <param name="indexer"></param>
        /// <returns></returns>
        public static Dictionary<int,List<int>> ReverseIndexTableOnField(
            DataTable dt, string fieldName, IFieldIndexer indexer)
        {
            Dictionary<int,List<int>> reverseIndexes=new Dictionary<int, List<int>>();
            int colIndex = 0;
            for(int i=0;i<dt.Columns.Count;i++)
            {
                if(dt.Columns[i].ColumnName.ToLower()==fieldName.ToLower())
                {
                    colIndex = i;
                    break;
                }
            }
            Dictionary<int,List<int>> clusteredRowNums=new Dictionary<int, List<int>>();
            for(int i=0;i<dt.Rows.Count;i++)
            {
                if (dt.Rows[i][colIndex] != null && dt.Rows[i][colIndex] != DBNull.Value)
                {
                    indexer.IndexValue(i, dt.Rows[i][colIndex], ref reverseIndexes);
                }
            }
            while(reverseIndexes.Count>0)
            {
                int firstRevKey = reverseIndexes.Keys.First();
                List<int> rowNumbers = reverseIndexes[firstRevKey];
                List<int> clusterIDsContainingRows=new List<int>();
                foreach(int clusterID in clusteredRowNums.Keys)
                {
                    foreach (int rowNum in rowNumbers)
                    {
                        if (clusteredRowNums[clusterID].Contains(rowNum))
                        {
                            if (!clusterIDsContainingRows.Contains(clusterID))
                                clusterIDsContainingRows.Add(clusterID);
                            break;
                        }
                    }
                }
                if(clusterIDsContainingRows.Count>0)
                {
                    clusterIDsContainingRows.Sort();
                    int clusterID = clusterIDsContainingRows[0];
                    foreach(int clusterID2 in clusterIDsContainingRows)
                    {
                        foreach (int rowNum in clusteredRowNums[clusterID2])
                        {
                            if (!rowNumbers.Contains(rowNum))
                                rowNumbers.Add(rowNum);
                        }
                        if (clusterID2 != clusterID)
                            clusteredRowNums.Remove(clusterID2);
                    }
                    clusteredRowNums[clusterID] = rowNumbers;
                }
                else
                {
                    int clusterID = clusteredRowNums.Count + 1;
                    foreach(int existClusterID in clusteredRowNums.Keys)
                    {
                        if (existClusterID >= clusterID)
                            clusterID = existClusterID + 1;
                    }
                    clusteredRowNums.Add(clusterID, rowNumbers);
                }
                reverseIndexes.Remove(firstRevKey);
            }
            reverseIndexes = null;
            return clusteredRowNums;
        }
        
        /// <summary>
        /// 
        /// </summary>
        /// <param name="dt"></param>
        /// <param name="orFields"></param>
        /// <param name="fieldIndexers"></param>
        /// <returns></returns>
        public static Dictionary<int, List<int>> ReverseIndexTableOnFields(
            DataTable dt, List<List<string>> orFields, Dictionary<string,IFieldIndexer> fieldIndexers)
        {
            throw new NotImplementedException();
        }
    }
}
